

#include "typedef.h"
#include "fifo.h"
#include "usart_driver.h"
#include "protocol_bsp.h"
/*
协议格式：  header   length    cmd       data    sum
            55 AA   00 00    00 00     ******    00
header: 协议头,固定 55 AA
length: 长度,两字节 大端模式，包括[cmd data]
cmd:    命令，两字节 大端模式，
sum:    校验和 包括[length cmd data]
*/
#define PROTOCOL_COM    COM_USART3



void protocol_bsp_init(void)
{
	com_usart_init(PROTOCOL_COM,COM_BR_115200,OPTIONAL_NULL);
}

u16 protocol_bsp_protocol_frame_get(u8 * out_buff, u32 out_length)
{
	#define FRAME_MIN_LENGTH	7 //协议中最少的字节数
	#define IF_CONTINUE(x)	if(x){ current_size--; fifo_discard_one(Q); continue;}
	struct FIFO_S * Q = com_rx_fifo_get(PROTOCOL_COM);
	u16 current_size=0, frame_length=0;
	u8 checksum=0;

	current_size = fifo_get_length(Q);
	while(current_size >= FRAME_MIN_LENGTH)
	{
		//1：协议头判断
		IF_CONTINUE((fifo_get_data(Q,0) != 0x55) || (fifo_get_data(Q,1) != 0xAA))
		//2.长度缓存判断
		frame_length = (fifo_get_data(Q,2)<<8) | fifo_get_data(Q,3);
		frame_length += 5;//一条完整的帧的长度
		IF_CONTINUE(frame_length>out_length)
		//3.完整帧判断
		if(frame_length>current_size){// full frame
			frame_length=0;
			break;
		}
		out_buff[0]=0x55;
		out_buff[1]=0xAA;
		checksum=0;
		for(int i=2; i<frame_length; i++){
			out_buff[i] = fifo_get_data(Q, i);
			checksum ^= out_buff[i];
		}
		//4.校验判断
		IF_CONTINUE(checksum != 0)
		fifo_head_offset(Q,frame_length);
		return frame_length;//check ok
	}
	return 0;
}

u16 protocol_bsp_protocol_frame_send(u16 cmd,const u8 *data, u16 length)
{
	u8 buff[256]={0};
	u16 num=0;
	u8 checksum=0;

	buff[num++] = 0x55;
	buff[num++] = 0xAA;
	buff[num++] = ((length+2)>>8)&0xFF;
	buff[num++] = (length+2)&0xFF;

	buff[num++] = (cmd>>8)&0xFF;
	buff[num++] = (cmd)&0xFF;


	for(int i=0; i<length; i++)
		buff[num++] = data[i];

	for(int i=2; i<num; i++)
		checksum ^= buff[i];

	buff[num++] = checksum;

	com_send_data(PROTOCOL_COM,buff,num);

	return num;
}

void protocol_bsp_uninit(void)
{
	com_usart_uninit(PROTOCOL_COM);
}

